package elsearch

import (
	"context"
	"errors"
	"fmt"
	"github.com/olivere/elastic/v7"
)

type Es struct {
	clinet *elastic.Client
}

func NewClient(host string) (client *Es, err error) {
	//host := "http://192.168.1.139:9200"

	mclient, err := elastic.NewClient(elastic.SetSniff(false), elastic.SetURL(host))
	if err != nil {
		return nil, errors.New("创建es客户端失败:" + err.Error())
	}
	_, _, err1 := mclient.Ping(host).Do(context.Background())
	if err1 != nil {
		return nil, errors.New("es客户端连接失败:" + err1.Error())
	}

	//获取es版本
	version, err2 := mclient.ElasticsearchVersion(host)
	if err2 != nil {
		return nil, errors.New("获取es版本失败: " + err2.Error())
	}
	fmt.Println("es客户端版本为: ", version)
	es := &Es{clinet: mclient}

	return es, nil
}

/*
	判断索引是否存在
*/

func (es *Es) IndexExists(index ...string) (bool, error) {
	status, err := es.clinet.IndexExists(index...).Do(context.Background())
	if err != nil {
		return false, err
	}
	return status, nil
}

/*
	插入文档
	index 插入库
	id 文档主键
	document 数据
*/

func (es *Es) InsertDocument(index, id string, document interface{}) error {
	_, err := es.clinet.Index().Index(index).Id(id).BodyJson(document).Do(context.Background())
	return err
}

/*
	通过id搜索
*/

func (es *Es) SearchDocumentId(index, id string) (string, error) {
	do, err := es.clinet.Get().Index(index).Id(id).Do(context.Background())
	if err != nil {
		return "", err
	}

	if do.Found {
		return string(do.Source), nil
	}
	return "", nil
}

func (es *Es) SearchDocument(index string) {
	// Refresh
	_, err := es.clinet.Refresh().Index(index).Do(context.TODO())
	if err != nil {
		fmt.Println(err)
	}
}

/*
	查询文档中有几条记录
*/

func (es *Es) SearchDocumentCount(index string) (count int64, err error) {
	counts, err := es.clinet.Count(index).Do(context.TODO())
	if err != nil {
		return 0, err
	}
	return counts, nil
}

/*
	删除一个或多个索引
	indexes 索引
*/

func (es *Es) DeleteIndex(indexes ...string) error {
	status, err := es.clinet.IndexExists(indexes...).Do(context.Background())
	if err != nil {
		return err
	}
	if status {
		deleteIndex, err := es.clinet.DeleteIndex(indexes...).Do(context.Background())
		if err != nil {
			return err
		}
		if !deleteIndex.Acknowledged {
			return err
		}
	} else {
		return errors.New("索引不存在无法删除")
	}
	return nil
}

/*
	删除文档
	index 索引
	documentId 文档主键
*/

func (es *Es) DeleteDocument(index string, documentId string) error {
	status, err := es.clinet.IndexExists(index).Do(context.Background())
	if err != nil {
		return err
	}
	if status {
		_, err := es.clinet.Delete().Index(index).Id(documentId).Do(context.Background())
		if err != nil {
			return err
		}
	} else {
		return errors.New("文档不存在无法删除")
	}
	return nil
}

/*
	更新文档
	index 索引
	documentId 文档id
	document 数据
*/

func (es *Es) UpdateDocument(index, documentId string, document interface{}) error {
	_, err := es.clinet.Update().Index(index).Id(documentId).Doc(document).Do(context.Background())
	if err != nil {
		return err
	}
	return nil
}

/*
	更新或插入（数据已存在则更新数据，否则插入数据）
	index 索引
	documentId 文档id
	document 数据
*/

func (es *Es) UpdateOrInsertDocument(index, documentId string, document interface{}) error {
	_, err := es.clinet.Update().Index(index).Id(documentId).Doc(document).DocAsUpsert(true).Do(context.Background())
	return err
}
